iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
1
Software Development

以資料庫為開發核心,利用通用 API 玩轉後端資料存取的概念與實作系列 第 25

Day25:實作 ORM(一) 將 ORM Store Procedure 化的重要 SQL 語法

  • 分享至 

  • xImage
  •  

昨天已經將 ORM 的優缺點及為何要將 ORM Store Procedure 化的緣由都說明清楚。但是說來容易,如何實作? 雖然之前也有根據 MS-SQL 及 MariaDB 有說明入門及進階的 SQL 語法,但是寫 ORM 可不是件簡單的活,沒有三兩三,怎敢上梁山。

下面我再分別補充將 ORM Store Procedure 化會用到的更進階 SQL 語法。事實上,最核心的程式就是用來執行 [動態 SQL 指令]。

MS-SQL
execute sp_executesql @sql;

MySQL(MariaDB)
PREPARE runsql FROM @sql;
EXECUTE runsql;

MS-SQL

declare @sql nvarchar(max);
if @action = 'C' or @action = 'Insert'
  set @sql = 'Insert Into ' + @tablename + ' (' + @fields + ')' + ' Values (' + @datas + ')'
else if @action = 'U' or @action = 'Update'
  set @sql = 'update ' + @tablename + ' set ' + @updatedatas + ' where ' + @pkwhere
else if @action = 'D' or @action = 'Delete'
  set @sql = 'delete from ' + @tablename + ' where ' + @pkwhere;

begin try
  execute sp_executesql @sql;
end try
begin catch
  -- Execute the error retrieval routine.
  -- 或是也可 SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
  execute usp_GetErrorInfo;
end catch

MariaDB

set _uuid2 = uuid();
if _wheresql = '' then
  set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39),  
             ',count(*) from ', _tablename);
else
  /* 這裡應該也要考慮 jointables 的寫法(如果 _wheresql 有 ma. _tablename 就要加) */
  if position('ma.' in _wheresql) > 0 then
    set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39), 
               ',count(*) from ', _tablename, ' ma where ', _wheresql);
  else 
    set @sql = concat('Insert Into _split (guid, col) select ', char(39), _uuid2, char(39), 
               ',count(*) from ', _tablename, ' where ', _wheresql);
  end if;
end if;
/* select @sql; */
PREPARE runsql FROM @sql;
set SQL_SAFE_UPDATES = 0;
EXECUTE runsql;
DEALLOCATE PREPARE runsql;

MySQL(MariaDB) 的語法有一個坑要小心,請小心繞道。

set SQL_SAFE_UPDATES = 0;

另外關於 Error Handle,MS-SQL 的機制很完整,但是 MySQL(MariaDB 就有點遜)
PS:也有可能是我對 MariaDB 還不熟。

    /*
	  MySQL 的 Error Handel 目前只找到以下的寫法, 還想不到共用 function 的寫法
	*/
	DECLARE CONTINUE HANDLER FOR 1048
	begin
	  set _errcode = '1048';
	  set _errmsg = '主鍵值不能為空白或 null';
	end;
	DECLARE CONTINUE HANDLER FOR 1062 
	begin
	  set _errcode = '1062';
	  set _errmsg = '主鍵值重複,無法存檔!!';
	end;
	DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
	begin
	  -- set _errcode = '9999';
	  -- set _errmsg = '資料庫操作失敗, 請洽客服工程師協助';
	  GET DIAGNOSTICS CONDITION 1
      _errcode = RETURNED_SQLSTATE, _errmsg = MESSAGE_TEXT;
	end;

要將 ORM Store Procedure 化並不是非常困難的事,對 SQL 語法有一定的理解就不會太難。一旦寫好,您會發現帶來的效益非常巨大,基本的 CRUD 真的在彈指間就完成(當然,前端的程式也要組出對應的內容再呼叫 API),對開發資訊系統的效率,有非常大的提升。今天我們先談到這邊,明天會將 ORM 應具備的功能做詳細說明,並會配合幾個實際的前端呼叫的程式片段來說明,明天見。


上一篇
Day24:ORM 的概念及 Store Procedure 化的說明
下一篇
Day26:實作 ORM(二) orm_api 應具備的功能
系列文
以資料庫為開發核心,利用通用 API 玩轉後端資料存取的概念與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言